package com.xyht.sca_s.student_manage_system.modules.newTips.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.SmsNewTips;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.SmsNewTipsAndRecordEntity;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.SmsNewTipsRecord;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.req.SmsNewTipsRecordReq;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.resp.SmsNewTipsAndRecordRespEntity;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.resp.SmsTipsUserResp;
import com.xyht.sca_s.student_manage_system.modules.newTips.mapper.SmsNewTipsMapper;
import com.xyht.sca_s.student_manage_system.modules.newTips.mapper.SmsNewTipsRecordMapper;
import com.xyht.sca_s.student_manage_system.modules.newTips.mapper.SmsNewTipsRecordMpjMapper;
import com.xyht.sca_s.student_manage_system.modules.newTips.service.SmsNewTipsService;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsApplication;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.SmsApplicationResp;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.IsReadFlagConstant.TIPS_READ_FLAG_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.IsReadFlagConstant.TIPS_READ_FLAG_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.ReadRangeFlagConstant.READ_RANGE_SINGLE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.TipsTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsRecordStatusEnum.*;

/**
 * <p>
 * 新消息通知 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-04-20
 */
@Service
public class SmsNewTipsServiceImpl extends ServiceImpl<SmsNewTipsMapper, SmsNewTips> implements SmsNewTipsService {
    @Autowired
    private SmsNewTipsMapper smsNewTipsMapper;
    @Autowired
    private SmsNewTipsRecordMapper smsNewTipsRecordMapper;
    @Autowired
    private NewTipsUtil newTipsUtil;
    @Autowired
    private SmsNewTipsRecordMpjMapper smsNewTipsRecordMpjMapper;
    @Autowired
    private SmsApplicationMapper smsApplicationMapper;
    @Autowired
    private SmsUserMapper smsUserMapper;

    @Override
    public ResponseResult getTipsList(String user_id, Integer client_flag, Integer tips_type, Integer pageNum, Integer pageSize) {
        if (isNullOrEmpty(tips_type)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //超时置位
        newTipsUtil.expiredStatusSetting();

        MPJLambdaWrapper<SmsNewTipsRecord> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAll(SmsNewTipsRecord.class)
                .selectAll(SmsNewTips.class)
                .selectAs(SmsNewTipsRecord::getId, "recordId")
                .selectAs(SmsNewTips::getId, "tipsId")
                .selectAs(SmsNewTipsRecord::getCreateTime, "recordCreateTime")
                .selectAs(SmsNewTips::getCreateTime, "tipsCreateTime")
                .leftJoin(SmsNewTips.class, SmsNewTips::getId, SmsNewTipsRecord::getRecordTipsId)
                .eq(SmsNewTipsRecord::getRecordUserId, user_id)
                .orderByDesc(SmsNewTips::getCreateTime);

        switch (tips_type) {
            //待我审核-待我审核
            case TIPS_TYPE_ALLOW_WAIT_ME:
                mpjLambdaWrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue());
                break;
            //审核中-审核中
            case TIPS_TYPE_ALLOWING:
                mpjLambdaWrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue());
                break;
            //关于我的-待办待处理、待办完成消息、审核完成、审核未完成消息、抄送
            case TIPS_TYPE_ABOUT_ME:
                mpjLambdaWrapper.and(wrapper -> {
                    wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_MESSAGE.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_PASS.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_DENY.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_COPY.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_MESSAGE.getValue());
                });
                break;
            //被拒绝-被拒绝
            case TIPS_TYPE_REJECT:
                mpjLambdaWrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_REJECTED.getValue());
                break;
            //已结束-
            case TIPS_TYPE_FINISH:
                mpjLambdaWrapper.and(wrapper -> {
                    wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME_FINISH.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_EXPIRE.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_CANCEL.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING_FINISH.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_DEAL_FINISH.getValue());
                });
                break;
        }
        Page<SmsNewTipsAndRecordEntity> page = new Page<>(pageNum, pageSize);
        smsNewTipsRecordMpjMapper.selectJoinPage(page, SmsNewTipsAndRecordEntity.class, mpjLambdaWrapper);

        List<SmsNewTipsAndRecordEntity> joinPage = page.getRecords();
        List<SmsNewTipsAndRecordRespEntity> respEntityList = joinPage.stream()
                .map(respEntity -> {
                    SmsNewTipsAndRecordRespEntity smsNewTipsAndRecordRespEntity =
                            new SmsNewTipsAndRecordRespEntity();
                    BeanUtils.copyProperties(respEntity, smsNewTipsAndRecordRespEntity);

                    SmsApplication smsApplication = smsApplicationMapper.selectOne(new QueryWrapper<SmsApplication>()
                            .lambda()
                            .eq(SmsApplication::getAppType, respEntity.getAppType())
                            .eq(SmsApplication::getAppClient, client_flag));

                    if (smsApplication != null) {
                        SmsApplicationResp smsApplicationResp = new SmsApplicationResp();
                        BeanUtils.copyProperties(smsApplication, smsApplicationResp);
                        smsNewTipsAndRecordRespEntity.setApplicationResp(smsApplicationResp);
                    }

                    SmsUser smsUser = smsUserMapper.selectById(respEntity.getTipsCreator());
                    if (smsUser != null) {
                        SmsTipsUserResp smsTipsUserResp = new SmsTipsUserResp();
                        BeanUtils.copyProperties(smsUser, smsTipsUserResp);
                        smsNewTipsAndRecordRespEntity.setUserResp(smsTipsUserResp);
                    }

                    return smsNewTipsAndRecordRespEntity;
                })
                .filter(tipsFilter -> tipsFilter.getApplicationResp() != null)
                .collect(Collectors.toList());
        int total = (int) page.getTotal();

        return CommonResult.success(respEntityList, total);
    }

    @Override
    public ResponseResult tipsRead(SmsNewTipsRecordReq smsNewTipsRecordReq, String user_id) {
        if (isNullOrEmpty(smsNewTipsRecordReq.getRead_range()) || isNullOrEmpty(smsNewTipsRecordReq.getTips_type())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (smsNewTipsRecordReq.getRead_range() == READ_RANGE_SINGLE) {
            if (isNullOrEmpty(smsNewTipsRecordReq.getRecord_id())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            SmsNewTipsRecord tipsRecord = smsNewTipsRecordMapper.selectById(smsNewTipsRecordReq.getRecord_id());
            if (tipsRecord == null || isNullOrEmpty(tipsRecord.getId())) {
                return CommonResult.failed(CommonCodeEnum.TIPS_RECORD_ERR);
            }

            SmsNewTipsRecord smsNewTipsRecord = new SmsNewTipsRecord();
            smsNewTipsRecord.setId(smsNewTipsRecordReq.getRecord_id());
            smsNewTipsRecord.setIsRead(TIPS_READ_FLAG_TRUE);
            smsNewTipsRecordMapper.updateById(smsNewTipsRecord);
        } else {
//            if (smsNewTipsRecordReq.getTips_type() == TIPS_TYPE_ALLOW_WAIT_ME
//                    || smsNewTipsRecordReq.getTips_type() == TIPS_TYPE_ALLOWING) {
//                return CommonResult.failed(CommonCodeEnum.TIPS_TYPE_CAN_NOT_READ);
//            }

            SmsNewTipsRecord updateTipsRecord = new SmsNewTipsRecord();
            updateTipsRecord.setIsRead(TIPS_READ_FLAG_TRUE);
            QueryWrapper<SmsNewTipsRecord> updateQueryWrapper = new QueryWrapper<>();
            updateQueryWrapper.lambda()
                    .eq(SmsNewTipsRecord::getRecordUserId, user_id)
                    .eq(SmsNewTipsRecord::getIsRead, TIPS_READ_FLAG_FALSE);

            switch (smsNewTipsRecordReq.getTips_type()) {
                //关于我的-待办待处理、待办完成消息、审核完成、审核未完成消息、抄送
                case TIPS_TYPE_ABOUT_ME:
                    updateQueryWrapper.lambda().and(wrapper -> {
                        wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_MESSAGE.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_PASS.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_DENY.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_COPY.getValue());
                    });
                    break;
                //被拒绝-被拒绝
                case TIPS_TYPE_REJECT:
                    updateQueryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_REJECTED.getValue());
                    break;
                //待我审批
                case TIPS_TYPE_ALLOW_WAIT_ME:
                    updateQueryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue());
                    break;
                //审批中
                case TIPS_TYPE_ALLOWING:
                    updateQueryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue());
                    break;
                //已结束-
                case TIPS_TYPE_FINISH:
                    updateQueryWrapper.lambda().and(wrapper -> {
                        wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME_FINISH.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_EXPIRE.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_CANCEL.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING_FINISH.getValue())
                                .or()
                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_DEAL_FINISH.getValue());
                    });
                    break;
            }
            smsNewTipsRecordMapper.update(updateTipsRecord, updateQueryWrapper);
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult getRedPoint(String user_id) {
        //超时置位
        newTipsUtil.expiredStatusSetting();

        Map<String, Object> map = new HashMap<>();
        map.put("waitMeCount", getRedPointCount(TIPS_TYPE_ALLOW_WAIT_ME, user_id));
        map.put("allowingCount", getRedPointCount(TIPS_TYPE_ALLOWING, user_id));
        map.put("aboutMeCount", getRedPointCount(TIPS_TYPE_ABOUT_ME, user_id));
        map.put("rejectedCount", getRedPointCount(TIPS_TYPE_REJECT, user_id));
        map.put("finishCount", getRedPointCount(TIPS_TYPE_FINISH, user_id));

        return CommonResult.success(map);
    }

    private Integer getRedPointCount(Integer tips_type, String user_id) {
        QueryWrapper<SmsNewTipsRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsNewTipsRecord::getRecordUserId, user_id)
                .eq(SmsNewTipsRecord::getIsRead, TIPS_READ_FLAG_FALSE);

        switch (tips_type) {
            //待我审核-待我审核
            case TIPS_TYPE_ALLOW_WAIT_ME:
                queryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue());
                break;
            //审核中-审核中
            case TIPS_TYPE_ALLOWING:
                queryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue());
                break;
            //关于我的-待办待处理、待办完成消息、审核完成、审核未完成消息、抄送
            case TIPS_TYPE_ABOUT_ME:
                queryWrapper.lambda().and(wrapper -> {
                    wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_MESSAGE.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_PASS.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_DENY.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_COPY.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_MESSAGE.getValue());
                });
                break;
            //被拒绝-被拒绝
            case TIPS_TYPE_REJECT:
                queryWrapper.lambda().eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_REJECTED.getValue());
                break;
            //已结束-
            case TIPS_TYPE_FINISH:
                queryWrapper.lambda().and(wrapper -> {
                    wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME_FINISH.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_EXPIRE.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_CANCEL.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING_FINISH.getValue())
                            .or()
                            .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_DEAL_FINISH.getValue());
                });
                break;
        }

        Integer count = smsNewTipsRecordMapper.selectCount(queryWrapper);
        if (count == null) {
            count = 0;
        }
        return count;
    }


}
